
/*
 * Brief:   Bitmap Implementation.
 *
 * File:    core/tp_bitmap.h
 * Author:  huangsanyi <huangsanyi@gmail.com>
 *
 */

/*
 * History:
 * 1,2013-1-20,huangsanyi,created.
 */

#include "tp_typedef.h"
#include "tp_bitmap.h"
#include "tp_memory.h"

struct _TpBitmap
{
	int w;
	int h;
	int size;
	TpColor* bits;
};

/* Blend src pixel and dest pixel up according the alpha value of src pixel.  */
static inline void tp_bitmap_alpha_blend(TpColor* dest, TpColor* src)
{
	dest->b = (dest->b * (0xFF - src->a) + src->b * src->a) / 0xFF;
	dest->g = (dest->g * (0xFF - src->a) + src->g * src->a) / 0xFF;
	dest->r = (dest->r * (0xFF - src->a) + src->r * src->a) / 0xFF;

	return;
}

TpBitmap* tp_bitmap_create(int w, int h, const TpColor* color)
{
	TpBitmap* thiz = (TpBitmap*)tp_alloc(sizeof(TpBitmap));

	if (NULL != thiz)
	{
		int i, j;

		thiz->bits = (TpColor*)tp_alloc(sizeof(TpColor) * w * h);
		if(NULL == thiz->bits)
		{
			tp_free(thiz);
			thiz = NULL;
		}
        else
        {        
            thiz->w = w;
            thiz->h = h;
            thiz->size = w * h;
            for (i = 0; i < h; ++i)
            {
                for (j = 0; j < w; ++j)
                {
                    thiz->bits[i * w + j] = *color;
                }
            }
        }
	}

	return thiz;
}

void tp_bitmap_destroy(TpBitmap* thiz)
{
	if (NULL != thiz)
	{
		if (NULL != thiz->bits)
		{
			tp_free(thiz->bits);
		}
		tp_free(thiz);
	}

	return;
}

int tp_bitmap_width(TpBitmap* thiz)
{
	return NULL != thiz ? thiz->w : 0;
}

int tp_bitmap_height(TpBitmap* thiz)
{
	return NULL != thiz ? thiz->h : 0;
}

TpColor* tp_bitmap_bits(TpBitmap* thiz)
{
	return NULL != thiz ? thiz->bits : NULL;
}

int tp_bitmap_copy_to_data_bgra32(TpBitmap* bitmap, TpRect* rect, 
								  TpColor* data, int xo, int yo, int dw, int dh)
{
	int x = 0, y = 0, w = 0, h = 0;

	TpColor* src = NULL;
	TpColor* dest = NULL;
	int i = 0, j = 0;

	if(NULL == bitmap || NULL == rect || NULL == data)
    {
        return TP_RET_BADARGS;
    }

	x = rect->x;
	y = rect->y;
	w = rect->w;
	h = rect->h;

	/* 保证未超出源bitmap */
	if(bitmap->w < (x + w))
	{
		w = bitmap->w - x;
	}
	if(bitmap->h < (y + h))
	{
		h = bitmap->h - y;
	}

	/* 保证未超出目标拷贝区域，否则进行剪切 */
	if(dw < (xo + w))
	{
		w = dw - xo;
	}
	if(dh < (yo + h))
	{
		h = dh - yo;
	}

	src = bitmap->bits + bitmap->w * y + x;
	dest = data + dw * yo + xo;

	for(i = 0; i < h; ++i)
	{
		for (j = 0; j < w; ++j)
		{
			tp_bitmap_alpha_blend(dest + j, src + j);
		}

		src += bitmap->w;
		dest += dw;
	}

	return TP_RET_OK;
}

int tp_bitmap_copy_from_data_bgr32(TpBitmap *bitmap, TpRect *rect,
                                   TpColor *data, unsigned int xo, unsigned int yo, 
                                   unsigned int dw, unsigned int dh)
{
    int x  = 0, y = 0, w = 0, h = 0;

    if (NULL == bitmap || NULL == rect || NULL == data || 0 == dw || 0 == dh)
    {
        return TP_RET_BADARGS;
    }

    x = rect->x;
    y = rect->y;
    w = rect->w;
    h = rect->h;

    /* 确认bitmap中给定区域未越界 */

    return 0;
}
